package com.xzhuang.task.util;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
/**
 * 
 * @name  http协议请求工具
 */
public class HttpUtilX {
	private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);

	/** 设置基础配置 */
	private static RequestConfig getconfig() {
		return REQUEST_CONFIG;
	}
	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016年1月4日 下午2:46:02
	 * @Title:get
	 * @param url
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url) throws ClientProtocolException, IOException, URISyntaxException {
		return get(url, (List<NameValuePair>) null);
	}

	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016年1月4日 下午2:45:44
	 * @Title:get
	 * @param url
	 * @param params
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, Map<String, Object> params) throws ClientProtocolException, IOException, URISyntaxException {
		if (params == null || params.size() < 1) {
			return get(url);
		}
		return get(url, setNameValuePair(params));
	}

	/**
	 * <dl>
	 * 说明：get请求
	 * <dt></dt>
	 * <dd>默认编码UTF-8</dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016年1月4日 下午2:45:16
	 * @Title:get
	 * @param url
	 * @param params
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, List<NameValuePair> params) throws ClientProtocolException, IOException, URISyntaxException {
		return get(url, params, "UTF-8");
	}

	/**
	 * <dl>
	 * 说明：get基础方法
	 * <dt></dt>
	 * <dd></dd>
	 * </dl>
	 * @author liujinlei
	 * @date 2016年1月4日 下午6:41:13
	 * @Title:get
	 * @param url
	 * @param params
	 * @param defaultCharset 编码格式
	 * @return String
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String get(String url, List<NameValuePair> params, String defaultCharset) throws ClientProtocolException, IOException, URISyntaxException {
		if (defaultCharset == null || defaultCharset.trim().equals("")) {
			defaultCharset = "UTF-8";

		}

		if (url == null || url.trim().equals("")) {
			throw new ClientProtocolException("url is null");
		} else {
			if (params != null && params.size() > 0) {
				String string = EntityUtils.toString(new UrlEncodedFormEntity(params, defaultCharset));
				if (url.indexOf("?") != -1) {
					url += "&" + string;
				} else {
					url += "?" + string;
				}
			}
		}

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		//custom().setDefaultCookieStore(new BasicCookieStore()).setDefaultRequestConfig(getconfig()).build();
		try {
			final HttpGet httpget = new HttpGet(url);
			httpget.setConfig(getconfig());
			CloseableHttpResponse response = httpclient.execute(httpget);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					responseBody = EntityUtils.toString(entity, defaultCharset);
				}
				EntityUtils.consume(entity);
				return responseBody;
			} finally {
				response.close();
			}
		} finally {
			httpclient.close();
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("GET：{} 结果{}", new Object[] { url, responseBody });
			}
		}
	}

	/**
	 * post提交xml格式内容 update by liujie 2016-10-04
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static String doPost(String content,String url,String contentType) throws IOException {
		
		
		
		StringBuilder result = new StringBuilder();
        URL postUrl = new URL(url);  
        URLConnection con = postUrl.openConnection(); 
        con.setConnectTimeout(5000);
        con.setDoOutput(true);  
        con.setRequestProperty("Pragma", "no-cache");  
        con.setRequestProperty("Cache-Control", "no-cache"); 
        if(contentType!=null)
        {
        	con.setRequestProperty("Content-Type", contentType);  
        }
        OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());    
        out.write(new String(content.getBytes("UTF-8")));  
        out.flush();  
        out.close();  
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));  
        String line = "";  
        for (line = br.readLine(); line != null; line = br.readLine()) {  
        	result = result.append(line);
        }  
		return result.toString();
	}
	
	/**
	 * MaoZeYao
	 * 微信退款请求发送
	 * 携带证书
	 * @param content
	 * @param url
	 * @param mchid
	 * @return
	 * @throws IOException
	 */
	public static String doWeChatRefundPost(String content,String url,String mchid,String ca) throws IOException {
		CloseableHttpClient httpclient = null;
		try {
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			FileInputStream instream = new FileInputStream(new File(ca));// P12文件目录
			// FileInputStream instream = new FileInputStream(new File("D:/javaprojects/certificate/apiclient_cert.p12"));// P12文件目录
			try {
				/**
				 * 此处要改
				 */
				keyStore.load(instream, mchid.toCharArray());// 这里写密码..默认是你的MCHID
			} catch (CertificateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				instream.close();
			}

			// Trust own CA and all self-signed certs
			/**
			 * 此处要改
			 */
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray())// 这里也是写密码的
					.build();
			// Allow TLSv1 protocol only
			@SuppressWarnings("deprecation")
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
					null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
			httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			HttpPost httpost = new HttpPost(url); // 设置响应头信息
			httpost.addHeader("Connection", "keep-alive");
			httpost.addHeader("Accept", "*/*");
			httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			httpost.addHeader("Host", "api.mch.weixin.qq.com");
			httpost.addHeader("X-Requested-With", "XMLHttpRequest");
			httpost.addHeader("Cache-Control", "max-age=0");
			httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
			httpost.setEntity(new StringEntity(content, "UTF-8"));
			CloseableHttpResponse response = httpclient.execute(httpost);
			try {
				HttpEntity entity = response.getEntity();
				String xmlStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				EntityUtils.consume(entity);
				return xmlStr;
			} finally {
				response.close();
				httpclient.close();
			}
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * MaoZeYao
	 * 微信退款请求发送
	 * 携带证书
	 * @param content
	 * @param url
	 * @param mchid
	 * @return
	 * @throws IOException
	 */
	public static String doWeChatRefundPost1(String content,String url,String mchid,String ca) throws IOException {
		CloseableHttpClient httpclient = null;
		try {
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			FileInputStream instream = new FileInputStream(new File("D:/javaprojects/certificate/ygBapp.p12"));// P12文件目录
			// FileInputStream instream = new FileInputStream(new File("D:/javaprojects/v3/ygCore/yg-c-pay-api/src/main/resources/apiclient_cert.p12"));// P12文件目录
			//FileInputStream instream = new FileInputStream(new File("D:/javaprojects/v3/ygCore/yg-c-pay-api/src/main/resources/apiclient_cert1.p12"));// P12文件目录
			try {
				/**
				 * 此处要改
				 */
				keyStore.load(instream, mchid.toCharArray());// 这里写密码..默认是你的MCHID
			} catch (CertificateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				instream.close();
			}
			
			// Trust own CA and all self-signed certs
			/**
			 * 此处要改
			 */
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray())// 这里也是写密码的
					.build();
			// Allow TLSv1 protocol only
			@SuppressWarnings("deprecation")
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
					null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
			httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			HttpPost httpost = new HttpPost(url); // 设置响应头信息
			httpost.addHeader("Connection", "keep-alive");
			httpost.addHeader("Accept", "*/*");
			httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			httpost.addHeader("Host", "api.mch.weixin.qq.com");
			httpost.addHeader("X-Requested-With", "XMLHttpRequest");
			httpost.addHeader("Cache-Control", "max-age=0");
			httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
			httpost.setEntity(new StringEntity(content, "UTF-8"));
			CloseableHttpResponse response = httpclient.execute(httpost);
			try {
				HttpEntity entity = response.getEntity();
				String xmlStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				EntityUtils.consume(entity);
				return xmlStr;
			} finally {
				response.close();
				httpclient.close();
			}
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 
	 * @Description: 发起GET请求
	 * @param url  请求的URL需要传入的参数需提前挂载
	 * @throws IOException   
	 * @return 返回结果  
	 */
	public static String doGet(String url) throws IOException {
		StringBuilder result = new StringBuilder();
		
		URL getUrl = new URL(url);

		// 根据拼凑的URL，打开连接，URL.openConnection()函数会根据
		// URL的类型，返回不同的URLConnection子类的对象，在这里我们的URL是一个http，因此它实际上返回的是HttpURLConnection
		HttpURLConnection connection = (HttpURLConnection) getUrl
				.openConnection();

		// 建立与服务器的连接，并未发送数据
		connection.connect();

		// 发送数据到服务器并使用Reader读取返回的数据
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				connection.getInputStream()));

		String lines;
		while ((lines = reader.readLine()) != null) {
			result = result.append(lines);
		}

		reader.close();

		// 断开连接
		connection.disconnect();
		return result.toString();
	}
	
	private static final RequestConfig	REQUEST_CONFIG	= RequestConfig.copy(RequestConfig.custom().setCookieSpec(CookieSpecs.DEFAULT).setExpectContinueEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build()).setSocketTimeout(30000).setConnectTimeout(15000).build();

	public static String post(String url, Map<String, Object> params) throws Exception {
		return post(url, setNameValuePair(params));
	}
	
	public static String post(String url, List<NameValuePair> params) throws Exception {
		return post(url, params, "UTF-8");
	}
	
	public static String post(String url, List<NameValuePair> params, String defaultCharset) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }

		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			if (defaultCharset == null || defaultCharset.trim().equals("")) {
				defaultCharset = "UTF-8";
			}
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(REQUEST_CONFIG);
			if (params != null && params.size() > 0) {
				httppost.setEntity(new UrlEncodedFormEntity(params, defaultCharset));
			}
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, defaultCharset);
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();
		}
	}
	
	private static List<NameValuePair> setNameValuePair(Map<String, Object> params) {
		List<NameValuePair> paramsList = new LinkedList<NameValuePair>();
		for (String key : params.keySet()) {
			if (params.get(key) == null) {
				paramsList.add(new BasicNameValuePair(key, null));
			} else {
				paramsList.add(new BasicNameValuePair(key, params.get(key).toString()));
			}
		}
		return paramsList;
	}
	public static String doWeChatRefundQueryPost(String xml, String url,String ca,String mchid) throws Exception{
		CloseableHttpClient httpclient = null;
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			FileInputStream instream = new FileInputStream(new File(ca));// P12文件目录
			try {
				keyStore.load(instream, mchid.toCharArray());// 这里写密码..默认是你的MCHID
			} catch (CertificateException e) {
				e.printStackTrace();
			} finally {
				instream.close();
			}
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray())// 这里也是写密码的
					.build();
			// Allow TLSv1 protocol only
			@SuppressWarnings("deprecation")
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
					null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
			httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			HttpPost httpost = new HttpPost(url); // 设置响应头信息
			httpost.addHeader("Connection", "keep-alive");
			httpost.addHeader("Accept", "*/*");
			httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			httpost.addHeader("Host", "api.mch.weixin.qq.com");
			httpost.addHeader("X-Requested-With", "XMLHttpRequest");
			httpost.addHeader("Cache-Control", "max-age=0");
			httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
			httpost.setEntity(new StringEntity(xml, "UTF-8"));
			CloseableHttpResponse response = httpclient.execute(httpost);
			try {
				HttpEntity entity = response.getEntity();
				String xmlStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				EntityUtils.consume(entity);
				return xmlStr;
			} finally {
				response.close();
				httpclient.close();
			}
	}

	public static String postBody(String url, String body, ContentType bodyContentType) throws Exception {
		if (url == null || url.trim().equals("")) { throw new NullPointerException("url is null"); }
		if (bodyContentType == null) {
			bodyContentType = ContentType.APPLICATION_JSON;
		}
		String responseBody = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.setConfig(REQUEST_CONFIG);
			if (body != null && body.trim().length() > 0) {
				StringEntity entity = new StringEntity(body, "UTF-8");//解决中文乱码问题
				entity.setContentType(bodyContentType.toString());
				httppost.setEntity(entity);
			}
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity resEntity = response.getEntity();
				if (resEntity != null) {
					responseBody = EntityUtils.toString(resEntity, "UTF-8");
				}
				EntityUtils.consume(resEntity);
				return responseBody;
			} catch (Exception e) {
				throw e;
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			httpclient.close();

		}


	}
}
